home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*----------------------------------------------------------------
- *
- * vidmap - live video and movie video texture mapping example using
- * both VL (SGI Video Library) and MV (SGI movie library).
- *
- * 08/93 John Magdziarz, Silicon Graphics, Inc.
- *
- *----------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <X11/Xlib.h>
- #include <gl/gl.h>
- #include <gl/device.h>
- #include <gl/image.h>
- #include <gl/glws.h>
- #include "glxhelper.h"
- #include <sys/time.h>
- #include <sys/fcntl.h>
- #include <X11/keysym.h>
- #include <movie.h>
- #include <vl/vl.h>
-
-
- #define RGB_COMP 4 /* select a 4 component texture */
- #define DEF_FRAME_RATE 6
- #define MAX_RATE 30
- #define DEF_BUF_SIZE 2
- #define X_KEYMAGIC 8 /* One byte offset in keycodes */
- #define XKEY_TO_GLKEY(x) ((x) - X_KEYMAGIC + 1)
-
- VLServer svr;
- VLPath path;
- VLDevList devlist;
- VLNode src;
- VLNode drn;
- VLBuffer buffer;
- int devicenum = -1;
- char *deviceName;
- int vin = 0;
- int imageCount = 1;
- VLTransferDescriptor xferDesc;
- VLControlValue val;
-
- int imgWidth = 320;
- int imgHeight = 240;
- int width[] = { 512, 256, 128, 64, 32 };
- int height[] = { 256, 128, 64, 32, 16 };
-
- float minFilter[] = { TX_POINT, TX_BILINEAR,
- TX_MIPMAP_POINT, TX_MIPMAP_LINEAR,
- TX_MIPMAP_BILINEAR, TX_MIPMAP_TRILINEAR };
-
- char *minFilterName[] = { "TX_POINT", "TX_BILINEAR",
- "TX_MIPMAP_POINT", "TX_MIPMAP_LINEAR",
- "TX_MIPMAP_BILINEAR", "TX_MIPMAP_TRILINEAR" };
-
- float magFilter[] = { TX_POINT, TX_BILINEAR, TX_BILINEAR_LEQUAL,
- TX_TRILINEAR, TX_BICUBIC,
- TX_SHARPEN, TX_ADD_DETAIL };
-
- char *magFilterName[] = { "TX_POINT", "TX_BILINEAR" };
-
- float texprops[] = { TX_MINFILTER, TX_POINT,
- TX_MAGFILTER, TX_POINT,
- TX_WRAP, TX_REPEAT, TX_NULL};
-
- float tevprops[] = { TV_NULL };
-
- int captureFormat;
- Boolean video = FALSE;
- Boolean oneComp = TRUE;
- ulong transferSize;
- char *ringBuffer = 0;
- ulong *rgbFrame;
- int frameSize;
- static char *_progName;
- int xWinSize = 0, yWinSize = 0;
- int forced_node = 0;
- Boolean initTextureParams = TRUE;
- int zoom = 2;
- Boolean debug = FALSE;
- Boolean newImg = False;
- float transy = -80;
-
- MVid mymovie;
- MVid imgTrack;
- int movieLen;
- char *moviefn;
-
- Display* dpy;
- int scrn;
- Window win;
- XEvent event;
- Boolean grabNew = TRUE;
- Boolean moving = FALSE;
- Boolean buttonIsPressed = FALSE;
- Boolean bltImg = FALSE;
- int minFiltIndex = 0;
- int magFiltIndex = 0;
- int sizeIndex = 1;
- struct timeval starttime, endtime;
- int nframes = 0;
- struct timeval starttime, endtime;
- Boolean reportPerf = False;
- Screencoord xorg, xwidth, xmax, yorg, yheight, ymax;
-
- char *controlStr = "\
- Mouse controls:\n\
- \n\
- Mouse rotates the plane around the x and y axes.\n\
- Button down while moving mouse zooms in and out.\n\
- \n\
- Keyboard controls:\n\
- \n\
- b - toggles between texture mapping and fast bit-blitting (lrectwrite)\n\
- g - toggles on/off of grabbing new frames\n\
- p - toggles performance reporting (fps every 10 frames) default off\n\
- m - cycles through the texture map magnification filters\n\
- n - cycles through the texture map minification filters\n\
- q - toggles multiple images on same plane (1/4 texture map)\n\
- ESC - exit\n";
-
- unsigned long *image, *imageInter;
-
- /* Define texture and vertex coordinates */
- float t0[2] = {0., 0.}, v0[3] = {-32., 24.,0.};
- float t1[2] = {1., 0.}, v1[3] = {32., 24.,0.};
- float t2[2] = {1., 1.}, v2[3] = {32., -24.,0.};
- float t3[2] = {0., 1.}, v3[3] = {-23., -24.,0.};
-
-
- void
- printControls()
- {
- printf("%s", controlStr);
- }
-
- initVideo()
- {
- VLNode nodes[2];
- int vidsrc = 0;
- int frameSize;
- VLFraction fval;
-
- if (!(svr = vlOpenVideo(""))) {
- fprintf(stderr, "%s: couldn't open video\n", _progName);
- exit(1);
- }
-
- if (vlGetDeviceList(svr, &devlist) < 0) {
- fprintf(stderr,"%s: getting device list.\n",_progName);
- exit(1);
- }
-
-
- drn = vlGetNode(svr, VL_DRN, VL_MEM, VL_ANY);
- if (forced_node == 0)
- src = vlGetNode(svr, VL_SRC, VL_VIDEO, VL_ANY);
- else
- src = vlGetNode(svr, VL_SRC, VL_VIDEO, vin);
-
-
- /* create the path (just grab the first device) */
- if ((devicenum >= (int)devlist.numDevices) || (devicenum < -1))
- {
- if (devlist.numDevices == 1)
- fprintf(stderr,"%s: The device number must be 0\n",_progName);
- else
- fprintf(stderr,"%s: The device number must be between 0 and %d\n",
- _progName, devlist.numDevices-1);
- exit(1);
- }
-
- drn = vlGetNode(svr, VL_DRN, VL_MEM, VL_ANY);
- if (forced_node == 0)
- src = vlGetNode(svr, VL_SRC, VL_VIDEO, VL_ANY);
- else
- src = vlGetNode(svr, VL_SRC, VL_VIDEO, vin);
-
- if (devicenum == -1)
- {
- if ((path = vlCreatePath(svr, VL_ANY, src, drn)) < 0) {
- vlPerror(_progName);
- exit(1);
- }
- devicenum = vlGetDevice(svr, path);
- deviceName = devlist.devices[devicenum].name;
- }
- else
- {
- deviceName = devlist.devices[devicenum].name;
- if ((path = vlCreatePath(svr, devicenum, src, drn)) < 0) {
- vlPerror(_progName);
- exit(1);
- }
- }
-
-
- if (vlSetupPaths(svr, (VLPathList)&path, 1, VL_SHARE, VL_SHARE) < 0)
- {
- vlPerror(_progName);
- exit(1);
- }
-
- /* get the name of the device we're using */
-
- deviceName = devlist.devices[devicenum].name;
-
- vlGetControl(svr, path, drn, VL_OFFSET, &val);
- if (debug)
- printf("X offset = %d Y offset = %d\n", val.xyVal.x, val.xyVal.y);
-
- val.fractVal.numerator = 1;
- val.fractVal.denominator = zoom;
- vlSetControl(svr, path, drn, VL_ZOOM, &val);
-
- vlGetControl(svr, path, drn, VL_ZOOM, &val);
- if (debug)
- printf("zoom = %d/%d\n", val.fractVal.numerator, val.fractVal.denominator);
-
- vlGetControl(svr, path, drn, VL_SIZE, &val);
-
- imgWidth = val.xyVal.x;
- imgHeight = val.xyVal.y;
-
- fprintf(stderr, "grabbing size %dx%d\n", imgWidth, imgHeight);
-
-
- val.intVal = VL_PACKING_RGB_8;
- vlSetControl(svr, path, drn, VL_PACKING, &val);
-
- /* specify what path-related events we want to receive */
- vlSelectEvents(svr, path, VLTransferCompleteMask);
-
- frameSize = vlGetTransferSize(svr, path);
-
- buffer = vlCreateBuffer(svr, path, drn, imageCount);
- if (buffer == NULL)
- {
- perror("creating buffer");
- exit(1);
- }
- /* now the vl will talk to the hardware to setup the path */
-
- vlRegisterBuffer(svr, path, drn, buffer);
-
- xferDesc.mode = VL_TRANSFER_MODE_CONTINUOUS;
- xferDesc.count = 1;
- xferDesc.delay = 0;
- xferDesc.trigger = VLTriggerImmediate;
-
- vlBeginTransfer(svr, path, 0, NULL);
- }
-
-
- static void set_entry (GLXconfig* ptr, int b, int m, int a)
- {
- ptr->buffer = b;
- ptr->mode = m;
- ptr->arg = a;
- }
-
-
- initMovie()
- {
- int moviefd, maxfd, xfd, filefd;
- fd_set fdset, loopfdset;
-
- if (mvIsMovieFile(moviefn) == DM_FALSE) {
- fprintf(stderr, "%s: %s is not a movie file, exiting.\n",
- _progName, moviefn);
- exit(-1);
- }
- else if ((mvOpenFile(moviefn, O_RDONLY, &mymovie)) < 0) {
- fprintf(stderr, "could not open movie file %s\n", moviefn);
- exit(-1);
- }
-
- mvFindTrackByMedium( mymovie, DM_IMAGE, &imgTrack);
- movieLen = mvGetTrackLength(imgTrack);
- imgWidth = mvGetImageWidth(imgTrack);
- imgHeight = mvGetImageHeight(imgTrack);
-
- frameSize = imgWidth * imgHeight * sizeof(ulong);
- rgbFrame = (ulong *)malloc(frameSize);
-
- /* Bind the GL/X window we just created to the movie. */
- if (mvBindWindow(mymovie, dpy, win) < 0) {
- fprintf(stderr, "could not bind movie to window\n");
- exit(0);
- }
-
- /* Get the file descriptor responsible for communicating the
- events we'll get back from the movie player */
- if (mvGetEventFD(&moviefd) < 0) {
- fprintf(stderr, "could not get movie fd\n");
- exit(0);
- }
-
-
- /* decide which movie events we're interested in hearing. */
- mvSetSelectEvents(MV_EVENT_MASK_FRAME | MV_EVENT_MASK_STOP |
- MV_EVENT_MASK_ERROR);
-
- mvSetFrameDisplay(FALSE);
- mvSetCurrentFrame(mymovie, 0);
- mvSetLoopMode(mymovie, MV_LOOP_CONTINUOUSLY);
- }
-
-
- int createVideoWindow(int width, int height)
- {
- /* Create an X window configured for GL rendering, using
- the helper functions defined in glxhelper.c */
- win = GLXCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
- 100, 100, width, height, 0, GLXrgbDoubleBuffer);
- if (GLXwinset(dpy, win) < 0) {
- fprintf(stderr, "\nGLXwinset is < 0\n");
- exit(-1);
- }
-
- XSelectInput( dpy, win, ExposureMask | StructureNotifyMask | ButtonPressMask |
- KeyPressMask | PointerMotionHintMask | PointerMotionMask |
- ButtonReleaseMask );
- XMapWindow(dpy, win);
- XFlush(dpy);
- return(0);
- }
-
-
-
- int
- getVideoFrame()
- {
- VLInfoPtr info;
- VLEvent vlEvent;
-
- newImg = False;
- if (vlCheckEvent(svr, VLTransferCompleteMask, &vlEvent) == 0) {
- if (debug)
- printf("transfer event arrived\n");
- while ((info = vlGetLatestValid(svr, buffer)) == 0);
- rgbFrame = vlGetActiveRegion(svr, buffer, info);
- newImg = True;
- }
- }
-
-
- void getMovieFrame()
- {
- static int curFrame = 0;
-
- newImg = False;
- if (mvReadFrames(imgTrack, curFrame, 1, frameSize, rgbFrame) < 0) {
- fprintf(stderr, "could not read movie frame\n");
- mvGetErrno();
- exit(0);
- }
-
- if (++curFrame > movieLen - 1)
- curFrame = 0;
- newImg = True;
- }
-
-
- grabAndSetTex()
- {
- if (grabNew) {
- if (video) {
- getVideoFrame();
- if (!newImg)
- return;
- }
- else
- getMovieFrame();
-
- if (bltImg)
- lrectwrite(0, 0, imgWidth-1, imgHeight-1, rgbFrame);
- else if (!moving)
- texdef2d(1, RGB_COMP, imgWidth, imgHeight, (unsigned long *)rgbFrame,
- 1, texprops);
- }
-
- /*
- * tell the system that we're done with that frame
- */
- if (video) {
- gflush();
- vlPutFree(svr, buffer);
- }
-
- if (initTextureParams) {
- initTextureParams = FALSE;
- tevdef(1, 1, tevprops);
- tevbind(TV_ENV0, 1);
- texdef2d(1, RGB_COMP, imgWidth, imgHeight, (ulong *)rgbFrame, 1, texprops);
- texbind(TX_TEXTURE_0, 1);
- }
- }
-
-
- executeKey(int glKey)
- {
- switch(glKey){
- case XK_n: minFiltIndex = ++minFiltIndex % 6;
- texprops[1] = minFilter[minFiltIndex];
- printf("min filter = %s\n",
- minFilterName[minFiltIndex]);
- break;
- case XK_m: magFiltIndex = ++magFiltIndex % 2;
- texprops[3] = magFilter[magFiltIndex];
- printf("mag filter = %s\n",
- magFilterName[magFiltIndex]);
-
- break;
- case XK_c: if (oneComp == TRUE) {
- oneComp = FALSE;
- printf("4 component texture\n");
- }
- else {
- oneComp = TRUE;
- printf("1 component texture\n");
- }
-
- break;
- case XK_g: if (grabNew == TRUE) {
- grabNew = FALSE;
- printf("new img grabbing off\n");
- }
- else {
- grabNew = TRUE;
- printf("new img grabbing on\n");
- }
-
- break;
- case XK_b: if (bltImg == TRUE) {
- bltImg = FALSE;
- printf("texture mapping on\n");
- initTextureParams = TRUE;
- }
- else {
- bltImg = TRUE;
- printf("texture mapping off\n");
- }
- break;
- case XK_p: if (reportPerf) {
- printf("Performance measuring: Off\n");
- reportPerf = FALSE;
- }
- else {
- printf("Performance measuring: On\n");
- printf("Performance calculated every 10 frames.\n");
- reportPerf = TRUE;
- gettimeofday(&starttime);
- nframes = 0;
- }
- break;
- case XK_q: if ( t1[0] == 1.0 ) {
- t1[0] = 2.0;
- t2[0] = 2.0;
- t2[1] = 2.0;
- t3[1] = 2.0;
- }
- else {
- t1[0] = 1.0;
- t2[0] = 1.0;
- t2[1] = 1.0;
- t3[1] = 1.0;
- }
-
- break;
- case XK_Escape:
- texbind(TX_TEXTURE_0, 0);
- tevbind(TV_ENV0, 0);
- /* winclose(vidmap); */
- exit(0);
- break;
-
- } /* end switch */
-
- }
-
-
-
- main(int argc, char** argv)
- {
- short val;
- int stat;
- double perf;
- int mousex, mousey, lastmousex, lastmousey;
- int rotx, roty;
- Boolean first = TRUE;
- GLXconfig params[50];
- GLXconfig* next;
- GLXconfig* retconfig;
- Window rwin, swin;
- int rootx, rooty;
- unsigned int btns;
- int glKey;
- KeySym ks;
- int c;
- static Matrix identity = { 1,0,0,0,
- 0,1,0,0,
- 0,0,1,0,
- 0,0,0,1};
- _progName = argv[0];
-
- while ((c = getopt(argc, argv, "pdv:b:lz:")) != EOF) {
- switch(c) {
- case 'v':
- vin= atoi(optarg);
- forced_node = 1;
- break;
- case 'b':
- imageCount = atoi(optarg);
- printf("buffer size = %d\n", imageCount);
- break;
- case 'z':
- zoom = atoi(optarg);
- break;
- case 'l':
- bltImg = TRUE;
- break;
- case 'd':
- debug = TRUE;
- break;
- case 'p':
- reportPerf = TRUE;
- break;
- }
- }
-
- printControls();
-
- if (optind != argc) {
- video = FALSE;
- moviefn = argv[optind];
- }
- else
- video = TRUE;
-
- dpy = XOpenDisplay(0);
- if (!dpy) {
- fprintf(stderr, "cannot open display\n");
- return -1;
- }
-
- scrn = DefaultScreen(dpy);
-
- xorg = 200;
- xwidth = 320;
- xmax = xorg + xwidth;
- yorg = 100;
- yheight = 240;
- ymax = yorg + yheight;
-
- if (createVideoWindow(xwidth, yheight) < 0) {
- fprintf(stderr, "could not create window\n");
- exit(0);
- }
-
- if (video)
- pixmode(PM_TTOB, 1);
- else
- pixmode(PM_TTOB, 0);
-
- mmode(MPROJECTION);
- loadmatrix(identity);
- perspective(600, 1., 1., 1000.);
- mmode(MVIEWING);
- loadmatrix(identity);
-
- translate(0., 0., transy); /* Move poly away from viewer */
-
- /** wait til window is up before doing anything else ***/
- while (1) {
- XNextEvent(dpy,&event);
- if (event.type == Expose)
- break;
- }
-
- if (video)
- initVideo();
- else {
- initMovie();
- rotate(-1800,'z');
- rotate(-1800,'y');
- }
-
- grabAndSetTex();
-
- mousex = xwidth / 2;
- mousey = yheight / 2;
-
- while ( TRUE ){
- if (XPending(dpy)) {
- XNextEvent(dpy,&event);
- switch (event.type) {
- case KeyPress:
- ks = XLookupKeysym( &event.xkey, 0 );
- executeKey(ks);
- break;
-
- case ButtonPress:
- buttonIsPressed = True;
- break;
-
- case ButtonRelease:
- buttonIsPressed = False;
- break;
-
- case MotionNotify:
- XQueryPointer( dpy, win, &rwin, &swin, &rootx, &rooty,
- &mousex, &mousey, &btns);
- break;
-
- case ConfigureNotify: /* window was resized */
- /* inform movie lib window was resized. As a side
- * effect, this also resizes the GL viewport */
- xwidth = event.xconfigure.width;
- yheight = event.xconfigure.height;
- reshapeviewport();
- printf("window resized\n");
- break;
-
- }
- }
-
- cpack(0x00000000);
- clear();
-
- moving = FALSE;
- if (mousex != lastmousex) {
- lastmousex = mousex;
- rotx = (xwidth / 2) - mousex;
- moving = TRUE;
- }
-
- if (mousey != lastmousey) {
- if (buttonIsPressed) {
- transy = .6 * (lastmousey - mousey);
- translate(0., 0., transy);
- lastmousey = mousey;
- }
- else {
- lastmousey = mousey;
- roty = (yheight / 2) - mousey;
- }
- moving = TRUE;
- }
-
- grabAndSetTex();
-
- if (!bltImg) {
- cpack(0xffffffff);
-
- pushmatrix();
-
- rotate(rotx * 10,'y');
- rotate(-roty * 10,'x');
-
- bgnpolygon();
- t2f(t0); v3f(v0);
- t2f(t1); v3f(v1);
- t2f(t2); v3f(v2);
- t2f(t3); v3f(v3);
- endpolygon();
-
- popmatrix();
- swapbuffers();
- }
- else if (newImg) {
- swapbuffers();
- }
-
- if ((!bltImg || newImg) && reportPerf) {
- if (++nframes >= 10) {
- gettimeofday(&endtime);
- perf = (double)(nframes)
- / (((double)((endtime.tv_sec - starttime.tv_sec) * 1000000
- + (endtime.tv_usec - starttime.tv_usec))) / 1000000.0);
- nframes = 0;
- starttime = endtime;
- fprintf(stderr, "%5.2f Frames Per Second\n", perf);
- }
- }
-
- }
- texbind(TX_TEXTURE_0, 0);
- }
-